package top.zsyle.movie.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.zsyle.movie.domain.MovieTicket;
import top.zsyle.movie.domain.UserMovie;
import top.zsyle.movie.dto.GetMiddleDto;
import top.zsyle.movie.dto.MovieTicketDto;
import top.zsyle.movie.exception.GlobalExceptionEnum;
import top.zsyle.movie.feign.MovieService;
import top.zsyle.movie.mapper.UserMapper;
import top.zsyle.movie.result.JsonResult;
import top.zsyle.movie.service.IUserService;
import top.zsyle.movie.utils.AssertUtil;
import top.zsyle.user.domain.User;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zhongshiyi
 * @since 2023-01-02
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private MovieService movieService;



    @Override
    public JsonResult buyById(MovieTicketDto dto) {
        Integer count = dto.getCount();
        JsonResult jsonResult = movieService.get(dto.getMovieTicketId());
        Object movieObj = jsonResult.getData();
        //返回拖地数据
        if (movieObj == null){
            return jsonResult;
        }
        String ObjStr = JSONObject.toJSONString(movieObj);
        MovieTicket movie = JSONObject.parseObject(ObjStr, MovieTicket.class);
//        MovieTicket movie = (MovieTicket) movieObj;
        //电影票售罄了
        boolean boo = movie.getStock()<=0;
        AssertUtil.isFalse(boo,GlobalExceptionEnum.MOVIE_TICKET_IS_NULL_EXCETRION);
        //判断电影票库存是否支持购买
        boolean boo2 = movie.getStock()-count < 0;
        AssertUtil.isFalse(boo2,GlobalExceptionEnum.MOVIE_TICKET_IS_NOT_ENOUGH_EXCEPTION);
        //判断该用户余额是否充足
        User user = selectById(1);//张三
        Long finalPrice = Long.valueOf(count) * movie.getPrice();
        long newBalance = user.getPrice() - finalPrice;
        boolean boo3 = newBalance < 0;
        AssertUtil.isFalse(boo3,GlobalExceptionEnum.USER_BALANCE_IS_NOT_ENOUGH_EXCEPTION);
        //并修改修改用户余额
        user.setPrice(newBalance);
        updateById(user);
        //查询是否有当前用户的中间表
        GetMiddleDto middleDto = new GetMiddleDto();
        middleDto.setUserId(user.getId());
        middleDto.setMovieTicketId(movie.getId());
        jsonResult = movieService.getMiddleByUserIdAndMovieId(middleDto);
        Object middleObj = jsonResult.getData();
        if (middleObj == null){
            //新增电影票和中间表数据
            saveMiddle(movie,user.getId(),count);
        }else{
            ObjStr = JSONObject.toJSONString(middleObj);
            UserMovie middle = JSONObject.parseObject(ObjStr, UserMovie.class);
            middle.setCount(middle.getCount()+count);
            movieService.saveOrUpdateMiddle(middle);
        }
        //修改电影票库存
        movie.setStock(movie.getStock()-count);
        jsonResult = movieService.saveOrUpdate(movie);
        return jsonResult;
    }

    /**
     * 消费电影票
     * @param dto
     * @return
     */
    @Override
    public JsonResult Consume(MovieTicketDto dto) {
        Integer count = dto.getCount();
        //查询当前用户是否有此电影票
        JsonResult jsonResult = movieService.getUserMovie(dto.getMovieTicketId());
        Object userMovieObj = jsonResult.getData();
        AssertUtil.isNotNull(userMovieObj,GlobalExceptionEnum.MOVIE_TICKET_IS_NULL_EXCEPTION);
        String ObjStr = JSONObject.toJSONString(userMovieObj);
        UserMovie userMovie = JSONObject.parseObject(ObjStr, UserMovie.class);
        //电影票已经被使用
        boolean boo = userMovie.getCount() <= 0;
        AssertUtil.isFalse(boo,GlobalExceptionEnum.MOVIE_TICKET_IS_USED_EXCEPTION);
        //判断电影票是否过期
        jsonResult = movieService.get(userMovie.getMovieTicketId());
        Object MovieTicketObj = jsonResult.getData();
        AssertUtil.isNotNull(MovieTicketObj,GlobalExceptionEnum.MOVIE_TICKET_IS_NULL_EXCEPTION);
        ObjStr = JSONObject.toJSONString(MovieTicketObj);
        MovieTicket movie = JSONObject.parseObject(ObjStr, MovieTicket.class);
        //当前时间
        Date date = new Date();
        boolean boo1 = date.getTime() > movie.getEndTime();
        AssertUtil.isFalse(boo1,GlobalExceptionEnum.MOVIE_TICKET_IS_OVER_TIME_EXCEPTION);
        //电影票消费 修改中间表
        userMovie.setCount(userMovie.getCount()-count);
        jsonResult = movieService.saveOrUpdateMiddle(userMovie);
        return jsonResult;
    }

    /**
     * 新增用户随机送一张电影票
     * @param entity
     * @return
     */
    @Override
    public boolean insert(User entity) {
        super.insert(entity);
        //随机送一张电影票必须是没有过期的
        Wrapper<MovieTicket> wrapper = new EntityWrapper<>();
        long time = new Date().getTime();
//        Wrapper<MovieTicket> end_time = wrapper.gt("end_time", time);
        JsonResult jsonResult = movieService.list();
        Object listObj = jsonResult.getData();
        AssertUtil.isNotNull(listObj,GlobalExceptionEnum.MOVIE_TICKET_IS_NOT_EXIST_EXCEPTION);
        String ObjStr = JSONObject.toJSONString(listObj);
        List<MovieTicket> movieList = JSONObject.parseArray(ObjStr,MovieTicket.class);
        //随机列表
        List<Long> newList = new ArrayList<>();
        movieList.forEach(m->{
            newList.add(m.getId());
        });

        //保存中间表
        Random rand = new Random();
        Long movieTicketId = newList.get(rand.nextInt(newList.size()));

        for (MovieTicket movieTicket : movieList) {
            if (movieTicket.getId().equals(movieTicketId)){
                saveMiddle(movieTicket,entity.getId(),1);
                return true;
            }
        }
        return true;
    }

    private void saveMiddle(MovieTicket movie, Long userId, Integer count) {
        UserMovie userMovie = new UserMovie();
        userMovie.setUserId(userId);
        userMovie.setMovieTicketId(movie.getId());
        userMovie.setCount(count);
        movieService.saveOrUpdateMiddle(userMovie);
    }
}
